<template>
    <canvas id="PoPo" ref="PoPo" />
</template>
<script>
export default {
    name: "PoPo",
    props: {
        conf: {
            type: Object,
            default: () => {},
        },
    },
    data() {
        return {
            defaultConf: {
                modeMap: ["up", "float", "down"],
                mode: "down", // 运动模式
                count: 50, // 数量
                size: 10, // 大小
                randomSize: true, // 随机大小
                colors: ["rgba(255,243,125,1)", "rgba(232,163,114,1)", "rgba(255,138,224,1)", "rgba(114,118,232,1)", "rgba(169,255,239,1)"],
                randomColor: true, // 随机颜色
                speed: 0.1, // 运动速度
                icon: "star", // star / circle / snow / imgURL
                hornOfStar: 5 // N角星
            },
            itemList: [],
            angle: 0,
        };
    },
    methods: {
        getRandom(min, max) {
            return Math.floor(Math.random()*(max - min + 1) + min);
        }
    },
    created() {
        const icon_xue =
            "";

        this.$nextTick(() => {
            let img = new Image(); // 创建img元素
            let [w, h] = [window.innerWidth, window.innerHeight];
            let { conf, itemList, angle, defaultConf } = this;
            let { modeMap, mode, count, size, randomSize, colors, randomColor, speed, icon, hornOfStar } = Object.assign({}, defaultConf, conf);

            let canvas = this.$refs.PoPo;
            let ctx = canvas.getContext("2d");
            canvas.width = w;
            canvas.height = h;

            for (let i = 0; i < count; i++) {
                // x,y圆心掉的坐标位置，r代表圆的半径，d每个圆的每个圆之间的间距，c代表的颜色
                itemList.push({
                    x: Math.random() * w,
                    y: Math.random() * h,
                    d: Math.random() * count,
                    r: randomSize ? Math.random() * size : size,
                    c: randomColor ? colors[i % 4] : colors[0],
                });
            }

            if (!["star", "circle"].includes(icon)) {
                img.onload = function() {
                    window.requestAnimationFrame(draw); // 执行和调用函数
                };
                img.src = icon === "snow" ? icon_xue : icon; // 设置图片源地址
            } else {
                //执行和调用函数
                window.requestAnimationFrame(draw);
            }

            //绘画的函数
            function draw() {
                ctx.clearRect(0, 0, w, h);
                for (let i = 0; i < count; i++) {
                    let { x, y, r, d, c } = itemList[i];
                    // 绘制圆形
                    function createCircle() {
                        ctx.beginPath();
                        ctx.moveTo(x, y);
                        ctx.fillStyle = c;
                        ctx.arc(x, y, r, 0, Math.PI * 2);
                        ctx.fill();
                        ctx.closePath();
                        ctx.fillStyle = c;
                        ctx.strokeStyle = c; // borderColor
                        ctx.fill();
                        ctx.stroke();
                    }
                    // 绘制多角星
                    function createStar() {
                        /**
                         * 绘制n角星
                         * @param ctx
                         * @param count 星星数量
                         * @param R 中心到顶点距离
                         * @param r 中心到凹点距离
                         * @param x 左上角X坐标Y
                         * @param y 左上角坐标
                         * @param rot 旋转角度
                         * @param configJson 配置信息
                         */

                        ctx.beginPath();
                        let count = hornOfStar,
                            R = 2 * r,
                            rot = 15,
                            border = 0;
                        for (let i = 0; i < count; i++) {
                            let perDeg = 360 / count;
                            let degA = perDeg / 2 / 2;
                            let degB = 360 / (count - 1) / 2 - degA / 2 + degA;
                            ctx.lineTo(
                                Math.cos(((degA + perDeg * i - rot) / 180) * Math.PI) * R + x + border + R * Math.cos((degA / 180) * Math.PI),
                                -Math.sin(((degA + perDeg * i - rot) / 180) * Math.PI) * R + y + border + R
                            );
                            ctx.lineTo(
                                Math.cos(((degB + perDeg * i - rot) / 180) * Math.PI) * r + x + border + R * Math.cos((degA / 180) * Math.PI),
                                -Math.sin(((degB + perDeg * i - rot) / 180) * Math.PI) * r + y + border + R
                            );
                        }
                        ctx.closePath();
                        ctx.fillStyle = c;
                        ctx.strokeStyle = c; // borderColor
                        ctx.fill();
                        ctx.stroke();
                    }
                    // 绘制图像
                    function createImg() {
                        // 执行drawImage语句
                        ctx.drawImage(img, x, y, r * 4, r * 2);
                    }
                    if (icon === "star") createStar();
                    else if (icon === "circle") createCircle();
                    else createImg();
                }
                drop();
            }

            // 掉落
            // 记住两个公式： Math.sin(弧度)返回是一个 0 1 -1 的数字 Math.cos(1 0 -1 ) 自由体
            const drop = () => {
                angle += 0.01;
                for (let i = 0; i < count; i++) {
                    let item = itemList[i];
                    item.x += Math.cos(angle) * 0.2;
                    if (mode === "down") item.y += item.r * speed;
                    if (mode === "up") item.y -= item.r * speed;
                    if (mode === "fload") item.y += Math.cos(angle + item.d) * 0.5;
                    //越界处理
                    if (item.x >= w + size || item.x <= 0 - size || item.y >= h + size || item.y <= 0 - size) {
                        if (mode === "up") {
                            item.y = h + size - 1;
                            item.x = w * Math.random();
                        } else if (mode === "float") {
                            item.y = h * Math.random();
                            item.x = w * Math.random();
                        } else if (mode === "down") {
                            item.y = 1 - size;
                            item.x = w * Math.random();
                        }
                    }
                }
                window.requestAnimationFrame(draw);
            };
        });
    },
};
</script>
<style scoped>
#PoPo {
    position: fixed;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    pointer-events: none;
    z-index: 9999;
}
</style>
